package cn.itsource.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.itsource.constants.CacheConstants;
import cn.itsource.constants.ErrorCode;
import cn.itsource.constants.RConst;
import cn.itsource.domain.dto.DriverSettingRedisDto;
import cn.itsource.dto.Codes;
import cn.itsource.exception.GlobalException;
import cn.itsource.mapper.DriverSettingMapper;
import cn.itsource.pojo.domain.DriverSetting;
import cn.itsource.pojo.dto.DriverOnLineDto;
import cn.itsource.result.JSONResult;
import cn.itsource.template.WechatTemplate;
import cn.itsource.api.LoginFeignClient;
import cn.itsource.pojo.domain.Driver;
import cn.itsource.mapper.DriverMapper;
import cn.itsource.pojo.domain.Login;
import cn.itsource.service.IDriverService;
import cn.itsource.utils.IdUtil;

import cn.itsource.utils.NameUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 司机对象 服务实现类
 * </p>
 *
 * @author lifan
 * @since 2024-09-03
 */
@Service
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver> implements IDriverService {

    @Autowired
    private WechatTemplate wechatTemplate;

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private LoginFeignClient loginFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DriverSettingMapper driverSettingMapper;


    @Override
//    @GlobalTransactional(name = "driver-wechat-register",rollbackFor = Exception.class)
    public void driverRegister(Codes codes) {
        //通过自动装配获取到openid
        String openId = wechatTemplate.getOpenId(codes.getWechatCode());
        //获取手机号的token
//        String accessToken = wechatTemplate.getAccessToken();
        //手机号
//        String phoneNumber = wechatTemplate.getPhoneNumber(accessToken, codes.getPhoneCode());

        // 构建查询条件 eq()等于
//        QueryWrapper<Driver> wrapper = new QueryWrapper<Driver>().eq("openId", openId);
        //方法引用 ，好处就是Driver::getOpenId，避免出错openid如果写错就不行，上面一直自己写有可能某个字母大小写问题，下面直接点出来
        LambdaQueryWrapper<Driver> wrapper = new LambdaQueryWrapper<Driver>()
                .eq(Driver::getOpenId, openId)//查询条件
                .select(Driver::getOpenId); //这个是只用openid做查询字段，如果不加，sql语句查询字段会是所有，就是from前面的字段，不加相当于是*号
        //查询
        Driver driver1 = driverMapper.selectOne(wrapper);
        // 一个微信只能注册一次
        if (driver1 == null){
            //同步到uaa 登录表login里去
            loginFeignClient.create(getLogin(openId));
            Driver driver = new Driver();
            driver.setId(IdUtil.getId());
            driver.setCreateTime(new Date());
            driver.setOpenId(openId);
            driver.getPhone();
            super.save(driver);
        }else {
            throw new GlobalException(ErrorCode.PARAM_PHONE_EXIST);
        }
    }

    @Override
    public JSONResult onLine(DriverOnLineDto onLineDto) {
        //1保存司机坐标redis
        GeoOperations<String,Object> geo = redisTemplate.opsForGeo();
        //获取坐标纬度和经度
        Point point = new Point(onLineDto.getLongitude(), onLineDto.getLatitude());
        //把键key和坐标，司机id存进redis中
        geo.add(CacheConstants.DRIVER_POINT,point, StpUtil.getLoginIdAsLong());
        redisTemplate.expire(CacheConstants.DRIVER_POINT+StpUtil.getLoginIdAsLong(),
                RConst.Num.BASE_LONG_5, TimeUnit.MINUTES);

        //2保存当前司机的配置  redis
        DriverSetting setting = driverSettingMapper.selectById(StpUtil.getLoginIdAsLong());
        DriverSettingRedisDto driverSettingRedisDto = new DriverSettingRedisDto();
        BeanUtils.copyProperties(setting,driverSettingRedisDto);
        driverSettingRedisDto.setListenService(true);
        redisTemplate.opsForValue()
                .set(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong(),driverSettingRedisDto);
        return JSONResult.success();
    }

    @Override
    public JSONResult refresh(DriverOnLineDto onLineDto) {
        //1.保存当前司机的坐标
        GeoOperations<String, Object> geo = redisTemplate.opsForGeo();
        Point point = new Point(onLineDto.getLongitude(),onLineDto.getLatitude());
        Long add = geo.add(CacheConstants.DRIVER_POINT, point, StpUtil.getLoginIdAsLong());
        if(add == RConst.Num.INT_1){
            redisTemplate.expire(CacheConstants.DRIVER_POINT+StpUtil.getLoginIdAsLong()
                    ,RConst.Num.BASE_LONG_5, TimeUnit.MINUTES);
        }
        return JSONResult.success();
    }

    @Override
    public JSONResult offline() {
        redisTemplate.opsForGeo().remove(CacheConstants.DRIVER_POINT,StpUtil.getLoginIdAsLong());
        redisTemplate.delete(CacheConstants.DRIVER_POINT_SETTING+StpUtil.getLoginIdAsLong());
        return JSONResult.success();
    }

    private static Login getLogin(String openId) {
        Login login = Login.builder().build();
        //生成uuid
        login.setId(IdUtil.getId());
        //用户名
        login.setUsername(NameUtil.getName());
        // 密码
        login.setPassword("123456");
        //账号类型
        login.setType(RConst.Num.INT_1);
        // 账户启动
        login.setEnabled(true);
        //管理员
        login.setAdmin(RConst.Num.INT_0);
        //昵称
        login.setNickName(NameUtil.getName());
        //微信id
        login.setOpenId(openId);
        //姓名
        login.setNickName(NameUtil.getName());
        //创建时间
        // 获取当前的日期和时间
        login.setCreateTime(new Date());
        return login;
    }

}
